package com.github.linkoog.model_designer.ide.editer.dbmodel.right_editer;

import com.github.linkoog.model_designer.ide.editer.*;
import com.github.linkoog.model_designer.ide.editer.common.*;
import com.github.linkoog.model_designer.ide.editer.dbmodel.DBModelConstants;
import com.github.linkoog.model_designer.ide.editer.dbmodel.domain.TableNavigatable;
import com.github.linkoog.model_designer.ide.editer.dbmodel.right_editer.table.DbtableInfoJTable;
import com.github.linkoog.model_designer.utils.Assert;
import com.github.linkoog.model_designer.utils.YamlReadUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.ui.ToolbarDecorator;
import com.intellij.util.OpenSourceUtil;
import org.jetbrains.yaml.YAMLElementGenerator;
import org.jetbrains.yaml.psi.*;

import javax.swing.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class TableListPanelBuilder {

    private static final Logger LOGGER = Logger.getInstance(TableListPanelBuilder.class);

    private final Project project;
    private final VirtualFile virtualFile;
    private final YAMLElementGenerator yamlElementGenerator;
    private Callback callback;

    private JPanel myMainPanel;
    private ToolbarDecorator toolbarDecorator;
    private DbtableInfoJTable dbtableInfoJTable;

    public TableListPanelBuilder(Project project, VirtualFile virtualFile){
        this.project = project;
        this.virtualFile = virtualFile;
        this.yamlElementGenerator = YAMLElementGenerator.getInstance(project);

        initUiPanel();
    }


    private void initUiPanel(){
        dbtableInfoJTable = new DbtableInfoJTable();
        dbtableInfoJTable.getSelectionModel().addListSelectionListener(e -> {

        });

        dbtableInfoJTable.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                final JTable table = (JTable) e.getSource();
                int row = table.rowAtPoint(e.getPoint()); //获得行位置
                int col = table.columnAtPoint(e.getPoint()); //获得列位置
                if (callback != null){
                    callback.callback();
                }

                if (row == -1 || col == -1){
                    table.clearSelection();
                    return;
                }

                TableVo rowData = (TableVo)dbtableInfoJTable.getTableInfoModel().getRowData(row);

                Map<String, ColumnVo> comcolMap = virtualFile.getUserData(DBModelConstants.DB_MODEL_COMMOM_COLUMNS_KEY);
                YAMLKeyValue tableKeyValue = getTableKeyValue(rowData.getName());
                TableVo tableVo = parseTableKeyValue(comcolMap, tableKeyValue);

                if (col == 2){
                    //点击行中的ddl列
                    DDLSqlDialog ddlSqlDialog = new DDLSqlDialog(project, tableVo);
                    ddlSqlDialog.showAndGet();
                    return;
                }

                if (col == 3){
                    DBTableEditDialog dbTableEditDialog = new DBTableEditDialog(project, virtualFile, tableVo);
                    dbTableEditDialog.showAndGet();
                    return;
                }


                OpenSourceUtil.navigate(true, tableVo.getNavigatable());
            }
        });


        toolbarDecorator = ToolbarDecorator.createDecorator(dbtableInfoJTable);
        /*toolbarDecorator.setAddAction(anActionButton -> {

        });

        toolbarDecorator.setRemoveAction(anActionButton -> {

        });*/

        /*DefaultActionGroup actionGroup = new DefaultActionGroup();
        ShowDDLAction showDDLAction = new ShowDDLAction(yamlFile, yamlKeyValue,"show ddl",null, Icons.SQL_2);
        actionGroup.add(showDDLAction);
        //toolbarDecorator.setActionGroup();

        toolbarDecorator.*/

        myMainPanel = toolbarDecorator.createPanel();
        //myMainPanel.setPreferredSize(JBUI.size(240,-1));
    }


    public void resetTableList(){
        YAMLFile yamlFile = (YAMLFile) PsiManager.getInstance(project).findFile(virtualFile);
        if (yamlFile == null){
            return;
        }

        final YAMLDocument root = yamlFile.getDocuments().get(0);
        if (root == null) {
            getDbtableInfoJTable().getTableInfoModel().reset(new ArrayList<>());
            return;
        }

        YAMLMapping rootMapping = PsiTreeUtil.findChildOfType(root, YAMLMapping.class);
        if (rootMapping == null) {
            getDbtableInfoJTable().getTableInfoModel().reset(new ArrayList<>());
            return;
        }


        Map<String, ColumnVo> comcolMap = virtualFile.getUserData(DBModelConstants.DB_MODEL_COMMOM_COLUMNS_KEY);
        ArrayList<TableNavigatable> tableNavigatableList = new ArrayList<>();
        for (YAMLKeyValue yamlKeyValue : rootMapping.getKeyValues()) {
            final String key = yamlKeyValue.getKeyText();
            if (DBModelConstants.DATASOURCES.equals(key)  || DBModelConstants.COMMON_COLUMNS.equals(key)){
                continue;
            }

            // table节点
            TableVo tableVo = parseTableKeyValue(comcolMap, yamlKeyValue);
            tableNavigatableList.add(tableVo);
        }

        getDbtableInfoJTable().getTableInfoModel().reset(tableNavigatableList);
    }

    private YAMLKeyValue getTableKeyValue(String name){
        YAMLFile yamlFile = (YAMLFile) PsiManager.getInstance(project).findFile(virtualFile);
        final YAMLDocument root = yamlFile.getDocuments().get(0);
        Assert.isTrue(root != null, "YAMLDocument is null!");
        YAMLMapping rootMapping = PsiTreeUtil.findChildOfType(root, YAMLMapping.class);
        Assert.isTrue(rootMapping != null, "rootMapping is null!");
        YAMLKeyValue tableKeyValue = rootMapping.getKeyValueByKey(name);
        Assert.isTrue(tableKeyValue != null && tableKeyValue.getValue() != null && tableKeyValue.getValue() instanceof YAMLMapping, "tableKeyValue is error!");
        return tableKeyValue;
    }

    private TableVo parseTableKeyValue(Map<String, ColumnVo> comcolMap, YAMLKeyValue tableKeyValue){
        String comment = "";
        List<Column> columns = new ArrayList<>();
        final YAMLValue value = tableKeyValue.getValue();
        if (value instanceof YAMLMapping){
            YAMLMapping tableMapping = (YAMLMapping)value;
            YAMLKeyValue commentKeyValue = tableMapping.getKeyValueByKey("comment");
            if (commentKeyValue != null){
                comment = commentKeyValue.getValueText();
            }

            YAMLKeyValue columnsKeyValue = tableMapping.getKeyValueByKey("columns");
            if (columnsKeyValue != null && columnsKeyValue.getValue() != null && (columnsKeyValue.getValue() instanceof YAMLMapping)){
                YAMLMapping columnsMapping = (YAMLMapping)columnsKeyValue.getValue();
                columns = YamlReadUtil.readTableColumns(comcolMap, columnsMapping);
            }
        }

        TableVo tableVo = new TableVo();
        tableVo.setName(tableKeyValue.getKeyText());
        tableVo.setComment(comment);
        tableVo.setColumns(columns);
        tableVo.setNavigatable(tableKeyValue);
        return tableVo;
    }



    public void filterTable(String tableName){
        dbtableInfoJTable.getTableInfoModel().filter(tableName);
    }


    public JPanel getMyMainPanel() {
        return myMainPanel;
    }

    public ToolbarDecorator getToolbarDecorator() {
        return toolbarDecorator;
    }

    public DbtableInfoJTable getDbtableInfoJTable() {
        return dbtableInfoJTable;
    }

    public Callback getCallback() {
        return callback;
    }

    public void setCallback(Callback callback) {
        this.callback = callback;
    }

    public static boolean isDoubleClick(MouseEvent e) {
        return e != null && e.getClickCount() > 0 && e.getClickCount() % 2 == 0;
    }
}
